import { AfterViewInit, Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from '@angular/core';
import { HttpRequestService } from '../core/services/http-request.service';

// import * as BpmnJS from 'bpmn-js/dist/bpmn-navigated-viewer.production.min.js';
import { CamundaBpmnViewerService } from './camunda-bpmn-viewer.service';

declare const BpmnJS: any;

/**
 * Camunda bpmn viewer to display the diagram and current progress based on processDefinitionId and processInstanceId.
 * 
 * The official documents.
 * https://bpmn.io/toolkit/bpmn-js/walkthrough
 * https://github.com/bpmn-io/bpmn-js-example-angular
 * https://github.com/bpmn-io/bpmn-js-examples
 */
@Component({
    selector: 'op-camunda-bpmn-viewer',
    templateUrl: './camunda-bpmn-viewer.component.html',
    providers: [CamundaBpmnViewerService]
})
export class CamundaBpmnViewerComponent implements AfterViewInit, OnChanges, OnDestroy, OnInit {
    @Input() processDefinitionId: string;
    @Input() processInstanceId: string;

    // Retrieves DOM element reference
    @ViewChild('viewer') private el: ElementRef;

    containerHeight: number = 800;

    // Instantiate BpmnJS with component
    private viewer = new BpmnJS();

    private canvas: any;
    private overlays: any;

    constructor(private bpmnViewerService: CamundaBpmnViewerService, private httpRequestService: HttpRequestService) { }

    ngOnInit(): void { }

    ngAfterViewInit(): void {
        // Attachs BpmnJS instance to DOM element
        this.viewer.attachTo(this.el.nativeElement);
    }

    ngOnChanges(changes: SimpleChanges): void {
        if (changes.processDefinitionId?.currentValue) {
            this.showDiagram();
        }

        if (this.processDefinitionId && changes.processInstanceId?.currentValue) {
            this.showProgress();
        }
    }

    ngOnDestroy(): void {
        // Destroyes BpmnJS instance
        this.viewer.destroy();
    }

    /**
     * Shows a camunda bpmn diagram by process definition id.
     */
    showDiagram(): void {
        if (this.processDefinitionId) {
            let me = this;

            // Gets the diagram xml content from server.
            me.bpmnViewerService.getProcessDefinitionModelByProcessDefinitionId(me.processDefinitionId).subscribe((res: any) => {
                me.viewer.importXML(res, (err: any) => {
                    if (err) {
                        return console.error('Could not import BPMN 2.0 diagram', err);
                    }

                    me.canvas = me.viewer.get('canvas');
                    me.overlays = me.viewer.get('overlays');

                    // Zooms to fit full viewport
                    me.canvas.zoom('fit-viewport');
                });
            });
        }
    }

    /**
     * Shows the process progress by process instance id.
     * The process instance must match the diagram's process definition.
     */
    showProgress(): void {
        if (this.processInstanceId) {
            let me = this;

            // Gets all historic info and marks on the diagram which is completed with is in progress.
            me.bpmnViewerService.getHistoricProcessInstance(me.processInstanceId).subscribe((res: any) => {
                if (res.result) {
                    res.result.activities.forEach((item: any) => {
                        if (item.endTime != null) {
                            // Adds marker to highlight the historic activity.
                            me.canvas.addMarker(item.activityId, 'historic-activity');
                        } else {
                            // Marks the current activity
                            // Attachs an overlay to a node for comment.
                            me.overlays.add(item.activityId, 'note', {
                                position: {
                                    bottom: 0,
                                    right: 0
                                },
                                html: '<div class="diagram-note">当前处理</div>'
                            });

                            // Adds marker to hightlight current activity
                            me.canvas.addMarker(item.activityId, 'current-activity');
                        }
                    });
                }
            });
        }
    }
}